<!--
 * @Author: zzr
 * @Date: 2025-08-19 14:05:49
 * @LastEditors: zzr
 * @Description: 
-->
<template>
  <div class="content-audit-container pt-30 pl-10">
    <el-card class="main-card">
      <!-- 上传区域 -->
      <div class="upload-section">
        <el-tabs v-model="activeTab" @tab-change="tabChange">
          <!-- 文本审核 -->
          <el-tab-pane label="文本审核" name="text">
            <div class="audit-config">
              <el-form :inline="true" :model="textConfig" label-width="100px">
                <el-form-item label="检测类型">
                  <el-select v-model="textConfig.eventType" placeholder="请选择">
                    <el-option
                      v-for="opt in getStrDictOptions('ai_review_text_event')"
                      :key="opt.label"
                      :label="opt.label"
                      :value="opt.value"
                    ></el-option>
                  </el-select>
                </el-form-item>
              </el-form>
            </div>
            <el-input
              v-model="reviewText"
              type="textarea"
              :rows="8"
              placeholder="请输入需要审核的文本内容"
              resize="none"
              :disabled="textResult ? true : false"
            ></el-input>
            <div class="action-buttons">
              <el-button
                class="liner-btn-opacity liner-btn"
                @click="submitText"
                :loading="loading"
                :disabled="!reviewText"
              >
                提交审核
              </el-button>
              <el-button @click="clearContent('text')">
                <el-icon><Delete /></el-icon>
                清空
              </el-button>
            </div>
          </el-tab-pane>

          <!-- 图片审核 -->
          <el-tab-pane label="图片审核" name="image">
            <div class="audit-config">
              <el-form :inline="true" :model="imageConfig" label-width="100px">
                <el-form-item label="检测场景">
                  <el-select v-model="imageConfig.imageCategories" multiple placeholder="请选择">
                    <el-option
                      v-for="opt in getStrDictOptions('ai_review_image_category')"
                      :key="opt.label"
                      :label="opt.label"
                      :value="opt.value"
                    ></el-option>
                  </el-select>
                </el-form-item>
                <el-form-item label="检测类型">
                  <el-select v-model="imageConfig.eventType" placeholder="请选择">
                    <el-option
                      v-for="opt in getStrDictOptions('ai_review_image_event')"
                      :key="opt.label"
                      :label="opt.label"
                      :value="opt.value"
                    ></el-option>
                  </el-select>
                </el-form-item>
              </el-form>
            </div>
            <ModelUpload
              v-model="imageFile"
              ref="uploadImage"
              drag
              accept="image/*"
              :max-size="10"
              :compress="true"
              auto-upload
            />
            <div class="image-preview" v-if="imageFile">
              <!-- <img :src="imagePreviewUrl" alt="预览图" /> -->
              <div class="action-buttons">
                <el-button
                  class="liner-btn-opacity liner-btn"
                  type="primary"
                  @click="submitImage"
                  :loading="loading"
                >
                  <el-icon><Search /></el-icon>
                  提交审核
                </el-button>
                <el-button @click="clearContent('image')">
                  <el-icon><Delete /></el-icon>
                  清除图片
                </el-button>
              </div>
            </div>
          </el-tab-pane>

          <!-- 音频审核 -->
          <el-tab-pane label="音频审核" name="audio" v-loading="taskLoading">
            <div class="audit-config">
              <el-form :inline="true" :model="audioConfig" label-width="100px">
                <el-form-item label="检测场景">
                  <el-select
                    class="w-200px"
                    v-model="audioConfig.audioCategories"
                    placeholder="请选择"
                    multiple
                  >
                    <el-option
                      v-for="item in getStrDictOptions('ai_review_audio_category')"
                      :key="item.label"
                      :label="item.label"
                      :value="item.value"
                    >
                    </el-option>
                  </el-select>
                </el-form-item>
                <el-form-item label="检测类型">
                  <el-select v-model="audioConfig.eventType" placeholder="请选择">
                    <el-option
                      v-for="item in getStrDictOptions('ai_review_audio_event')"
                      :key="item.label"
                      :label="item.label"
                      :value="item.value"
                    >
                    </el-option>
                  </el-select>
                </el-form-item>
              </el-form>
            </div>
            <ModelUpload
              v-model="audioFile"
              ref="uploadAudio"
              drag
              accept="audio/*"
              :max-size="50"
              auto-upload
            />
            <div class="audio-preview" v-if="audioFile">
              <!-- <div class="audio-info">
                <el-icon><Headset /></el-icon>
                <span>{{ audioFile.name }}</span>
                <span>({{ formatFileSize(audioFile.size) }})</span>
              </div> -->
              <div class="action-buttons">
                <el-button
                  class="liner-btn-opacity liner-btn"
                  type="primary"
                  @click="submitAudio"
                  :loading="loading"
                >
                  <el-icon><Search /></el-icon>
                  提交审核
                </el-button>
                <el-button @click="clearContent('audio')">
                  <el-icon><Delete /></el-icon>
                  清除音频
                </el-button>
              </div>
            </div>
          </el-tab-pane>

          <!-- 视频审核 -->
          <el-tab-pane label="视频审核" name="video" v-loading="taskLoading">
            <div class="audit-config">
              <el-form :inline="true" :model="videoConfig" label-width="100px">
                <el-form-item label="画面场景">
                  <el-select v-model="videoConfig.imageCategories" multiple placeholder="请选择">
                    <el-option
                      v-for="item in getStrDictOptions('ai_review_image_category')"
                      :key="item.label"
                      :label="item.label"
                      :value="item.value"
                    >
                    </el-option>
                  </el-select>
                </el-form-item>
                <el-form-item label="声音场景">
                  <el-select v-model="videoConfig.audioCategories" multiple placeholder="请选择">
                    <el-option
                      v-for="item in getStrDictOptions('ai_review_audio_category')"
                      :key="item.label"
                      :label="item.label"
                      :value="item.value"
                    >
                    </el-option>
                  </el-select>
                </el-form-item>
                <el-form-item label="检测类型">
                  <el-select v-model="videoConfig.eventType" placeholder="请选择">
                    <el-option
                      v-for="item in getStrDictOptions('ai_review_video_event')"
                      :key="item.label"
                      :label="item.label"
                      :value="item.value"
                    >
                    </el-option>
                  </el-select>
                </el-form-item>
              </el-form>
            </div>
            <ModelUpload
              v-model="videoFile"
              ref="uploadVideo"
              drag
              accept="video/*"
              :max-size="100"
              auto-upload
            />
            <div class="video-preview" v-if="videoFile">
              <!-- <video :src="videoPreviewUrl" controls></video> -->
              <div class="action-buttons">
                <el-button
                  class="liner-btn-opacity liner-btn"
                  type="primary"
                  @click="submitVideo"
                  :loading="loading"
                >
                  <el-icon><Search /></el-icon>
                  提交审核
                </el-button>
                <el-button @click="clearContent('video')">
                  <el-icon><Delete /></el-icon>
                  清除视频
                </el-button>
              </div>
            </div>
          </el-tab-pane>
        </el-tabs>
      </div>

      <!-- 审核结果 -->
      <div class="result-section" v-if="showResults">
        <h3 class="t-blue mb-10">审核结果</h3>

        <!-- 文本审核结果 -->
        <div class="text-result" v-if="activeTab === 'text' && textResult">
          <el-alert
            :title="`审核状态: ${getStatusText(textResult.suggestion)}`"
            :type="getStatusType(textResult.suggestion)"
            :closable="false"
          />

          <!-- <div class="highlight-text" v-if="textResult.suggestion !== 'pass'">
            <span v-html="highlightText(reviewText, textResult.details)"></span>
          </div> -->
          <template v-if="textResult.suggestion !== 'pass'">
            <HighLightText :text="reviewText" :details="textResult.details" />

            <el-table :data="processedDetails" border>
              <el-table-column label="违规类型">
                <template #default="{ row }">
                  {{ getLabelText(row.label) }}
                </template>
              </el-table-column>
              <el-table-column label="违规内容">
                <template #default="{ row }">
                  <div class="segment-item">
                    {{ row.segment }}
                    <!-- <span class="segment-position">
                      ({{ row.position[0] }}-{{ row.position[row.position.length - 1] }})
                    </span> -->
                  </div>
                </template>
              </el-table-column>
              <el-table-column label="位置">
                <template #default="{ row }">
                  第{{ row.position[0] }}-{{ row.position[row.position.length - 1] }}字符
                </template>
              </el-table-column>
              <el-table-column label="置信度">
                <template #default="{ row }">
                  <el-progress
                    :percentage="Math.round(row.confidence * 100)"
                    :status="getConfidenceStatus(row.confidence)"
                    :stroke-width="18"
                    :text-inside="true"
                  />
                </template>
              </el-table-column>
              <el-table-column label="建议">
                <template #default="{ row }">
                  <el-tag :type="getSuggestionTagType(row.suggestion)">
                    {{ getSuggestionText(row.suggestion) }}
                  </el-tag>
                </template>
              </el-table-column>
            </el-table>
          </template>
        </div>

        <!-- 图片审核结果 -->
        <div class="image-result" v-if="activeTab === 'image' && imageResult">
          <el-alert
            :title="`审核状态: ${getStatusText(imageResult.suggestion)}`"
            :type="getStatusType(imageResult.suggestion)"
            :closable="false"
          />
          <template v-if="imageResult.suggestion !== 'pass'">
            <!-- TODO 图片审核位置 -->
            <!-- <div class="image-with-markers" v-if="imageResult.suggestion !== 'pass'">
              <img :src="imagePreviewUrl" alt="审核结果" class="marked-image" />
              <div
                class="marker-box"
                v-for="(area, index) in imageResult.violationAreas"
                :key="index"
                :style="{
                  left: `${area.x}px`,
                  top: `${area.y}px`,
                  width: `${area.width}px`,
                  height: `${area.height}px`,
                }"
              ></div>
            </div> -->
            <el-table :data="imageResult.details" border>
              <el-table-column label="违规类型">
                <template #default="{ row }">
                  {{ getLabelText(row.category) }}
                </template>
              </el-table-column>
              <!-- <el-table-column label="违规内容">
                <template #default="{ row }">
                  <template v-if="row.segments && row.segments.length > 0">
                    {{ row.segments[0].segment }}
                  </template>
                </template>
              </el-table-column>
              <el-table-column label="位置">
                <template #default="{ row }">
                  <template v-if="row.segments && row.segments.length > 0">
                    第{{ row.segments[0].position[0] }}-{{
                      row.segments[0].position[row.segments[0].position.length - 1]
                    }}字符
                  </template>
                </template>
              </el-table-column> -->
              <el-table-column label="置信度" width="180">
                <template #default="{ row }">
                  <el-progress
                    :percentage="row.confidence * 100"
                    :status="getConfidenceStatus(row.confidence)"
                    :stroke-width="18"
                    :text-inside="true"
                  />
                </template>
              </el-table-column>
              <el-table-column label="建议">
                <template #default="{ row }">
                  <el-tag :type="getSuggestionTagType(row.suggestion)">
                    {{ getSuggestionText(row.suggestion) }}
                  </el-tag>
                </template>
              </el-table-column>
            </el-table>
            <!-- <el-table :data="imageResult.details" style="width: 100%" border>
              <el-table-column prop="type" label="违规类型" width="180" />
              <el-table-column label="违规区域" width="180">
                <template #default="{ row }">
                  X:{{ row.area.x }}, Y:{{ row.area.y }}, W:{{ row.area.width }}, H:{{
                    row.area.height
                  }}
                </template>
              </el-table-column>
              <el-table-column prop="confidence" label="置信度">
                <template #default="{ row }">
                  <el-progress
                    :percentage="row.confidence * 100"
                    :status="row.confidence > 0.8 ? 'exception' : 'warning'"
                  />
                </template>
              </el-table-column>
              <el-table-column prop="suggestion" label="建议" />
            </el-table> -->
          </template>
        </div>

        <!-- 音频审核结果 -->
        <div class="audio-result" v-if="activeTab === 'audio' && audioResult">
          <el-alert
            :title="`审核状态: ${getStatusText(audioResult.suggestion)} `"
            :type="getStatusType(audioResult.suggestion)"
            :closable="false"
          />

          <div class="audio-details" v-if="audioResult.suggestion !== 'pass'">
            <p class="p-10 t-gray">内容：{{ audioResult.audio_text }}</p>
            <el-table :data="processedAudioDetails" border>
              <el-table-column label="违规类型" width="120">
                <template #default="{ row }">
                  {{ getLabelText(row.label) }}
                </template>
              </el-table-column>
              <el-table-column label="时间位置" width="120">
                <template #default="{ row }">
                  {{ formatTime(row.start_time) }} - {{ formatTime(row.end_time) }}
                </template>
              </el-table-column>
              <el-table-column label="违规内容">
                <template #default="{ row }">
                  <div v-html="highlightAudioText(row)" class="audio-text-content"></div>
                </template>
              </el-table-column>
              <el-table-column label="建议" width="200">
                <template #default="{ row }">
                  <el-tag :type="getSuggestionTagType(row.suggestion)">
                    {{ getSuggestionText(row.suggestion) }}
                  </el-tag>
                </template>
              </el-table-column>
            </el-table>
          </div>
        </div>

        <!-- 视频审核结果 -->
        <div class="video-result" v-if="activeTab === 'video' && videoResult">
          <el-alert
            :title="`审核状态: ${getStatusText(videoResult.suggestion)} `"
            :type="getStatusType(videoResult.suggestion)"
            :closable="false"
          />

          <div class="video-details" v-if="videoResult.suggestion !== 'pass'">
            <!-- <div class="video-with-markers">
              <video :src="videoPreviewUrl" controls></video>
              <div class="video-timeline">
                <div
                  class="timeline-marker"
                  v-for="(violation, index) in videoResult.details"
                  :key="index"
                  :style="{
                    left: `${(violation.startTime / videoResult.duration) * 100}%`,
                    width: `${
                      ((violation.endTime - violation.startTime) / videoResult.duration) * 100
                    }%`,
                  }"
                  :title="`${violation.type} (${formatTime(violation.startTime)}-${formatTime(
                    violation.endTime
                  )})`"
                ></div>
              </div>
            </div> -->
            <div
              class="result-section"
              v-if="videoResult.image_detail && videoResult.image_detail.length"
            >
              <h4>画面违规详情</h4>
              <el-table :data="videoResult.image_detail" border>
                <el-table-column label="时间点" width="80">
                  <template #default="{ row }">
                    {{ formatTime(row.time) }}
                  </template>
                </el-table-column>
                <el-table-column label="违规类型" width="120">
                  <template #default="{ row }">
                    {{ getLabelText(row.category) }}
                  </template>
                </el-table-column>
                <el-table-column label="违规标签">
                  <template #default="{ row }">
                    <div v-for="(item, index) in row.detail" :key="index" class="tag-item">
                      {{ getLabelText(item.label) }}
                      <el-tag size="small" :type="getSuggestionTagType(item.suggestion)">
                        {{ getSuggestionText(item.suggestion) }}
                      </el-tag>
                    </div>
                  </template>
                </el-table-column>
                <el-table-column label="置信度" width="120">
                  <template #default="{ row }">
                    <div v-for="(item, index) in row.detail" :key="index" class="confidence-item">
                      <el-progress
                        class="mt-5 mb-5"
                        :percentage="Math.round(item.confidence * 100)"
                        :status="getConfidenceStatus(item.confidence)"
                        :stroke-width="16"
                        :text-inside="true"
                      />
                    </div>
                  </template>
                </el-table-column>
                <el-table-column label="建议" width="200">
                  <template #default="{ row }">
                    <el-tag :type="getSuggestionTagType(row.suggestion)">
                      {{ getSuggestionText(row.suggestion) }}
                    </el-tag>
                  </template>
                </el-table-column>
              </el-table>
            </div>

            <!-- 音频审核结果表格 -->
            <div
              class="result-section"
              v-if="videoResult.audio_detail && videoResult.audio_detail.length"
            >
              <h4>音频违规详情</h4>
              <el-table :data="videoResult.audio_detail" border>
                <el-table-column label="时间段" width="80">
                  <template #default="{ row }">
                    {{ formatTime(row.start_time) }} - {{ formatTime(row.end_time) }}
                  </template>
                </el-table-column>
                <el-table-column label="违规类型" width="120">
                  <template #default="{ row }">
                    {{ getLabelText(row.label) }}
                  </template>
                </el-table-column>
                <el-table-column label="违规内容">
                  <template #default="{ row }">
                    {{ row.audio_text || "无文本内容" }}
                  </template>
                </el-table-column>
                <el-table-column label="置信度" width="120">
                  <template #default="{ row }">
                    <el-progress
                      :percentage="Math.round(row.detail[0].confidence * 100)"
                      :status="getConfidenceStatus(row.detail[0].confidence)"
                      :stroke-width="18"
                      :text-inside="true"
                    />
                  </template>
                </el-table-column>
                <el-table-column label="建议" width="200">
                  <template #default="{ row }">
                    <el-tag :type="getSuggestionTagType(row.suggestion)">
                      {{ getSuggestionText(row.suggestion) }}
                    </el-tag>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </div>
        </div>
      </div>
    </el-card>
  </div>
</template>

<script setup>
import { ref, onBeforeUnmount, useTemplateRef } from "vue";
import { Search, Delete, UploadFilled, Headset } from "@element-plus/icons-vue";
import { getStrDictOptions } from "@/utils/dict";
import Compressor from "compressorjs";
import { updateFile } from "@/api/file";
import { AuditApi } from "@/api/ai/audit";

const activeTab = ref("text");
const reviewText = ref("");
const imageFile = ref(null);
const imagePreviewUrl = ref("");
const audioFile = ref(null);
const videoFile = ref(null);
const videoPreviewUrl = ref("");
const loading = ref(false);
const showResults = ref(false);
const textResult = ref(null);
const imageResult = ref(null);
const audioResult = ref(null);
const videoResult = ref(null);
const uploadimageRef = useTemplateRef("uploadImage");
const uploadvideoRef = useTemplateRef("uploadVideo");
const uploadaudioRef = useTemplateRef("uploadAudio");
// 轮询
const taskLoading = ref(false);
// 处理details数据，展开所有segments（添加空值检查）
const processedDetails = computed(() => {
  if (!textResult.value?.details) {
    console.log("无值返回[]");
    return [];
  }

  const result = [];
  textResult.value.details.forEach((detail) => {
    if (detail.segments && detail.segments.length > 0) {
      detail.segments.forEach((segment) => {
        result.push({
          label: detail.label,
          confidence: detail.confidence,
          suggestion: detail.suggestion,
          segment: segment.segment,
          position: segment.position,
          id: `${detail.label}-${segment.position.join("-")}`,
        });
      });
    }
  });

  return result;
});

// 处理音频详情数据
const processedAudioDetails = computed(() => {
  if (!audioResult.value?.details) {
    return [];
  }

  return audioResult.value.details.map((item) => ({
    ...item,
    id: `${item.label}-${item.start_time}-${item.end_time}`,
  }));
});

// 高亮显示音频文本
const highlightAudioText = (row) => {
  let text = row.audio_text || "";

  // 如果有segments，进行高亮替换
  if (row.segments && row.segments.length > 0) {
    row.segments.forEach((segment) => {
      if (segment.segment) {
        const escapedSegment = segment.segment.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
        const regex = new RegExp(escapedSegment, "g");
        text = text.replace(regex, `<span class="audio-highlight">${segment.segment}</span>`);
      }
    });
  }

  return text;
};

// 格式化时间（秒 -> 分:秒）
const formatTime = (seconds) => {
  if (seconds == null) return "--";
  const mins = Math.floor(seconds / 60);
  const secs = Math.floor(seconds % 60);
  return `${mins}:${secs.toString().padStart(2, "0")}`;
};
// 获取违规类型
const getLabelText = (label) => {
  const labelMap = {
    terrorism: "暴恐",
    porn: "色情",
    ban: "违禁",
    moan: "呻吟声",
    terrorism: "暴恐",
    abuse: "辱骂",
    ad: "广告",
    // customized：自定义（命中自定义词库中的关键词）,
    // 图片
    image_text: "图文审核",
    // 音频
    politics: "政治敏感",
    // 视频
    pornography: "色情内容",
    adult_product: "成人用品",
    sm: "SM内容",
  };
  return labelMap[label] || label;
};
// 获取置信度状态
const getConfidenceStatus = (confidence) => {
  return confidence > 0.8 ? "exception" : confidence > 0.6 ? "warning" : "success";
};
// 接口data
const reviewType = computed(() => {
  const typeDictMap = {
    text: "文本",
    image: "图片",
    video: "视频",
    audio: "音频",
  };
  return getStrDictOptions("ai_review_type").find((d) => {
    return d.label === typeDictMap[activeTab.value];
  })?.value;
});
// 审核配置
const textConfig = ref({
  eventType: undefined,
});
// 审核配置
const imageConfig = ref({
  imageCategories: [],
  eventType: undefined,
});

const audioConfig = ref({
  audioCategories: [],
  eventType: undefined,
});

const videoConfig = ref({
  imageCategories: [],
  audioCategories: [],
  eventType: undefined,
});
const pollingResults = (ref) => {
  simplePolling()
    .then((res) => {
      console.log("最终结果:", res);
      ref.value = res?.result;
      // 输出: { status: 'success', data: '任务完成!' }
    })
    .catch((error) => {
      console.error("轮询失败:", error);
    });
};
onMounted(() => {
  executeAudioVideoPolling(activeTab.value);
});
const tabChange = (val) => {
  console.log("val", val);
  showResults.value = false;
  clearContent("all");
  executeAudioVideoPolling(val);
};
// 音视频轮询逻辑(页面初始化 以及tab切换)
const executeAudioVideoPolling = (val) => {
  if (["audio", "video"].includes(val)) {
    console.log(
      "%c音视频轮询",
      "color: white; background-color: #f1738e; padding: 2px 5px; border-radius: 2px"
    );
    const curResult = val == "audio" ? audioResult : imageResult;
    pollingResults(curResult);
  }
};
// 组件卸载前清理内存
onBeforeUnmount(() => {
  clearContent("all");
});
// 统一清理方法
const clearContent = (type) => {
  switch (type) {
    case "text":
      textResult.value = null;
      reviewText.value = "";
      break;
    case "image":
      uploadimageRef.value.clear();
      imageResult.value = null;
      imageFile.value = "";
      break;
    case "audio":
      uploadaudioRef.value.clear();
      audioResult.value = null;
      audioFile.value = "";
      break;
    case "video":
      uploadvideoRef.value.clear();
      videoResult.value = null;
      videoFile.value = "";
      break;
    case "all":
      clearContent("text");
      clearContent("image");
      clearContent("audio");
      clearContent("video");
      break;
    default:
  }
  showResults.value = false;
};

// 提交文本审核
const submitText = async () => {
  if (!reviewText.value.trim()) {
    ElMessage.warning("请输入要审核的文本内容");
    return;
  }

  loading.value = true;
  showResults.value = false;

  try {
    // 模拟API调用
    // await new Promise((resolve) => setTimeout(resolve, 1000));
    const data = await AuditApi.reviewSync({
      reviewText: reviewText.value,
      reviewType: reviewType.value,
      ...textConfig.value,
    });
    console.log("审核结果", data);
    textResult.value = data.result;
    showResults.value = true;
  } catch (error) {
  } finally {
    loading.value = false;
  }
};
// 提交图片审核
const submitImage = async () => {
  if (!imageFile.value) {
    ElMessage.warning("请上传要审核的图片");
    return;
  }

  loading.value = true;
  showResults.value = false;
  try {
    const res = await AuditApi.reviewSync({
      url: imageFile.value,
      ...imageConfig.value,
      reviewType: reviewType.value,
    });
    imageResult.value = res.result;
    showResults.value = true;
  } catch (error) {
    // ElMessage.error("审核请求失败: " + error.message);
  } finally {
    loading.value = false;
  }
};

/**
 * 简单轮询函数
 * @param {Function} apiCall - 需要轮询的API函数
 * @param {Object} params - API参数
 * @param {number} [interval=1500] - 轮询间隔(毫秒)
 * @param {number} [maxAttempts=20] - 最大轮询次数
 * @returns {Promise} 返回API最终结果
 */
const simplePolling = async (interval = 1500, maxAttempts = 20) => {
  let attempts = 0;
  const queryRunningData = await AuditApi.queryRunning();
  const requestId = queryRunningData?.[0]?.requestId;
  if (!requestId) {
    console.log("没有任务");
    return null;
  }
  const poll = async () => {
    attempts++;
    taskLoading.value = true;
    try {
      const response = await AuditApi.queryAsync({
        requestId,
      });

      // 如果状态不是running，返回结果
      if (response?.status !== "running") {
        taskLoading.value = false;
        showResults.value = true;
        if (response?.status === "failed") {
          response.result = {
            suggestion: "failed",
            label: "审核失败",
          };
        }
        return response;
      }

      // 达到最大尝试次数则抛出错误
      if (attempts >= maxAttempts) {
        taskLoading.value = false;
        throw new Error("轮询超时，未获取最终结果");
      }

      // 继续轮询
      return new Promise((resolve) => {
        setTimeout(() => resolve(poll()), interval);
      });
    } catch (error) {
      console.error("轮询出错:", error);
      throw error;
    }
  };

  return poll();
};

// 提交音频审核
const submitAudio = async () => {
  if (!audioFile.value) {
    ElMessage.warning("请上传要审核的音频");
    return;
  }

  loading.value = true;
  showResults.value = false;
  try {
    const res = await AuditApi.reviewAsync({
      url: audioFile.value,
      ...audioConfig.value,
      reviewType: reviewType.value,
    });
    pollingResults(audioResult);
    // audioResult.value = res.result;
    // showResults.value = true;
  } catch (error) {
  } finally {
    loading.value = false;
  }
};

// 提交视频审核
const submitVideo = async () => {
  if (!videoFile.value) {
    ElMessage.warning("请上传要审核的视频");
    return;
  }

  loading.value = true;
  showResults.value = false;

  try {
    const res = await AuditApi.reviewAsync({
      url: videoFile.value,
      ...videoConfig.value,
      reviewType: reviewType.value,
    });
    pollingResults(videoResult);
  } catch (error) {
    // ElMessage.error("视频审核失败: " + error.message);
  } finally {
    loading.value = false;
  }
};
// 获取建议标签的类型
const getSuggestionTagType = (suggestion) => {
  const map = {
    block: "danger",
    pass: "success",
    review: "warning",
  };
  return map[suggestion] || "";
};

// 获取建议的友好文本
const getSuggestionText = (suggestion) => {
  const suggestionMap = {
    block: "包含敏感信息，不通过",
    pass: "通过",
    review: "需要人工复检",
  };
  return suggestionMap[suggestion] || suggestion;
};
// 格式化文件大小
const formatFileSize = (bytes) => {
  if (bytes === 0) return "0 Bytes";
  const k = 1024;
  const sizes = ["Bytes", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
};

// 获取状态文本
const getStatusText = (status) => {
  const map = {
    pass: "通过",
    block: "包含敏感信息，不通过",
    review: "需要人工复检",
    failed: "任务运行失败，请重试",
  };
  return map[status] || status;
};

// 获取状态类型
const getStatusType = (status) => {
  const map = {
    pass: "success",
    review: "warning",
    reject: "error",
    failed: "error",
  };
  return map[status] || "info";
};

// 模拟API响应数据
const mockTextApiResponse = {
  status: "reject", // pass, review, reject
  details: [
    {
      type: "政治敏感",
      position: [1, 5, 10], // 行, 开始字符, 结束字符
      content: "某些敏感内容",
      suggestion: "建议删除或修改",
    },
    {
      type: "不当言论",
      position: [1, 15, 20],
      content: "不当言论内容",
      suggestion: "建议删除",
    },
  ],
};

const mockImageApiResponse = {
  status: "reject", // pass, review, reject
  violationAreas: [
    { x: 100, y: 150, width: 80, height: 80 },
    { x: 200, y: 200, width: 50, height: 50 },
  ],
  details: [
    {
      type: "裸露内容",
      area: { x: 100, y: 150, width: 80, height: 80 },
      confidence: 0.92,
      suggestion: "建议模糊处理或删除",
    },
    {
      type: "暴力内容",
      area: { x: 200, y: 200, width: 50, height: 50 },
      confidence: 0.76,
      suggestion: "建议人工复核",
    },
  ],
};

const mockAudioApiResponse = {
  status: "review", // pass, review, reject
  duration: 183, // 音频时长(秒)
  details: [
    {
      type: "辱骂内容",
      startTime: 45.2,
      endTime: 47.8,
      content: "识别出的辱骂文本",
      confidence: 0.85,
      suggestion: "建议静音处理",
    },
    {
      type: "版权内容",
      startTime: 120.5,
      endTime: 135.2,
      content: "受版权保护的音乐片段",
      confidence: 0.78,
      suggestion: "建议人工复核",
    },
  ],
};

const mockVideoApiResponse = {
  status: "reject", // pass, review, reject
  duration: 240, // 视频时长(秒)
  details: [
    {
      type: "色情内容",
      startTime: 65.3,
      endTime: 68.7,
      area: { x: 100, y: 150, width: 80, height: 80 },
      confidence: 0.91,
      suggestion: "建议模糊处理或删除",
    },
    {
      type: "广告内容",
      startTime: 120.5,
      endTime: 125.8,
      area: { x: 200, y: 50, width: 150, height: 40 },
      confidence: 0.82,
      suggestion: "建议人工复核",
    },
    {
      type: "涉政内容",
      startTime: 180.2,
      endTime: 185.6,
      confidence: 0.88,
      suggestion: "建议删除",
    },
  ],
};
</script>

<style scoped lang="scss">
.content-audit-container {
  padding: 20px;
  .el-select {
    --el-select-width: 150px;
  }
}

.main-card {
  // max-width: 1200px;
  margin: 0 auto;
  margin-left: 10px;
  padding: 0 10px 20px 10px;
  background: var(--img-group-bg);
  border-radius: 10px;
  overflow: auto;
  border: none;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.upload-section {
  margin-bottom: 30px;
}

.audit-config {
  margin-bottom: 20px;
  padding: 15px;
  background: var(--nav-bg);
  border-radius: 4px;
}

.action-buttons {
  margin-top: 15px;
  display: flex;
  gap: 10px;
}

.image-preview {
  margin-top: 20px;
  text-align: center;
}

.image-preview img {
  max-width: 100%;
  max-height: 400px;
  border: 1px solid #eee;
}

.audio-preview {
  margin-top: 20px;
  padding: 15px;
  background: #f8f9fa;
  border-radius: 4px;

  .audio-info {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 15px;

    .el-icon {
      font-size: 24px;
      color: #409eff;
    }
  }
}

.video-preview {
  margin-top: 20px;
  text-align: center;

  video {
    max-width: 100%;
    max-height: 400px;
    background: #000;
  }
}

.result-section {
  margin-top: 30px;
  border-top: 1px solid #eee;
  padding-top: 20px;
}

.image-with-markers {
  position: relative;
  display: inline-block;
  margin: 20px 0;
}

.marked-image {
  max-width: 100%;
  max-height: 400px;
}

.marker-box {
  position: absolute;
  border: 2px solid red;
  background-color: rgba(255, 0, 0, 0.2);
  pointer-events: none;
}

.video-with-markers {
  position: relative;
  display: inline-block;
  margin: 20px 0;

  video {
    max-width: 100%;
    max-height: 400px;
    background: #000;
  }
}

.video-timeline {
  position: relative;
  height: 10px;
  background: #eee;
  margin-top: 5px;
  border-radius: 5px;
  overflow: hidden;

  .timeline-marker {
    position: absolute;
    height: 100%;
    background-color: rgba(255, 0, 0, 0.5);
    cursor: pointer;

    &:hover {
      background-color: rgba(255, 0, 0, 0.8);
    }
  }
}
// 音频表格
.audio-text-content {
  line-height: 1.6;
  word-break: break-all;
}

/* 高亮样式 */
.audio-text-content :deep(.audio-highlight) {
  background-color: rgba(255, 205, 210, 0.7);
  color: #d32f2f;
  padding: 1px 2px;
  border-radius: 2px;
  border-bottom: 1px dashed #f44336;
  font-weight: 500;
}

/* 不同类型的高亮颜色 */
.audio-text-content :deep(.audio-highlight-abuse) {
  background-color: rgba(255, 205, 210, 0.7);
  border-bottom-color: #f44336;
}

.audio-text-content :deep(.audio-highlight-porn) {
  background-color: rgba(244, 143, 177, 0.7);
  border-bottom-color: #e91e63;
}

.audio-text-content :deep(.audio-highlight-politics) {
  background-color: rgba(255, 152, 0, 0.7);
  border-bottom-color: #ff9800;
}

/* 表格样式优化 */
:deep(.el-table .cell) {
  line-height: 1.6;
}
</style>

<style>
.highlight-text {
  margin: 20px 0;
  padding: 15px;
  background: #f8f8f8;
  border-radius: 4px;
  line-height: 1.8;
}

/* 高亮违规文本基础样式 */
.highlight-violation {
  position: relative;
  display: inline-block;
}

/* 不同类型的高亮样式 */
.highlight-char {
  padding: 0 1px;
  position: relative;
}

.highlight-abuse {
  background-color: rgba(255, 205, 210, 0.5);
  border-bottom: 1px dashed #f44336;
}

.highlight-porn {
  background-color: rgba(244, 143, 177, 0.5);
  border-bottom: 1px dashed #e91e63;
}
.highlight-violation[data-type="abuse"] {
  background-color: rgba(255, 205, 210, 0.7); /* 辱骂 - 浅红色 */
  border-bottom: 1px dashed #f44336;
}

.highlight-violation[data-type="porn"] {
  background-color: rgba(244, 143, 177, 0.7); /* 色情 - 粉色 */
  border-bottom: 1px dashed #e91e63;
}

.highlight-violation[data-type="terrorism"] {
  background-color: rgba(255, 138, 128, 0.7); /* 暴恐 - 深红色 */
  border-bottom: 1px dashed #d32f2f;
}

.highlight-violation[data-type="ban"] {
  background-color: rgba(255, 171, 145, 0.7); /* 违禁 - 橙色 */
  border-bottom: 1px dashed #ff5722;
}

.highlight-violation[data-type="ad"] {
  background-color: rgba(255, 224, 178, 0.7); /* 广告 - 黄色 */
  border-bottom: 1px dashed #ff9800;
}

.highlight-violation[data-type="customized"] {
  background-color: rgba(197, 225, 165, 0.7); /* 自定义 - 浅绿色 */
  border-bottom: 1px dashed #8bc34a;
}

/* tooltip 样式 */
.highlight-violation:hover::after {
  content: attr(title);
  position: absolute;
  left: 50%;
  bottom: 100%;
  transform: translateX(-50%);
  background: #333;
  color: #fff;
  padding: 5px 10px;
  border-radius: 4px;
  font-size: 12px;
  white-space: pre-line;
  z-index: 100;
  min-width: 200px;
  max-width: 300px;
  pointer-events: none;
  margin-bottom: 5px;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}

/* 结果表格样式 */
.segment-item {
  padding: 4px 0;
  border-bottom: 1px dashed #eee;
}

.segment-item:last-child {
  border-bottom: none;
}

.segment-position {
  color: #999;
  font-size: 12px;
  margin-left: 8px;
}

.confidence-text {
  text-align: center;
  font-size: 12px;
  color: #666;
  margin-top: 4px;
}

:deep(.el-table .el-progress-bar) {
  padding-right: 0;
}
</style>
